import re
import logging
from fastapi import Request, HTTPException
from fastapi.responses import JSONResponse

from utils.generate_verfy_token import verify_token

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# 定义不需要验证 Token 的接口路径，使用正则表达式来处理动态参数路径([\w-]+ 表示匹配一个或多个连续的单词字符（字母、数字、下划线）或者连字符)
EXCLUDED_PATHS = [
    r"^/$",
    r"^/docs$",
    r"^/openapi.json$",
    r"^/user/login/account$",
    r"^/user/api/send_sms_code$",
    r"^/user/register$",
    r"^/user/login/quick$",
    r"^/products/secondary_categories$",
    r"^/products/product_list$",
    r"^/products/products_by_category/[\d]+$",
    r"^/products/product_detail/[\d]+$",
    r"^/products/spec_option_list$",
    r"^/products/[\d]+/specs_and_options$",
    r"^/products/get_toppings/[\d]+$",
    r"^/homepage/carousel$",
    r"^/payment/alipay/notify$",
    r"^/payment/wechat/notify$",
    r"^/api/purchase/[\d]+/[\d]+/[\d]+$"
]

async def token_validation_middleware(request: Request, call_next):
    # print("token_validation_middleware", request.headers)
    path = request.url.path
    # 检查当前请求路径是否在不需要验证的列表中
    for pattern in EXCLUDED_PATHS:
        if re.match(pattern, path):
            return await call_next(request)
    # 跳过 OPTIONS 请求（预检请求不需要验证 Token）
    if request.method == "OPTIONS":
        return await call_next(request)
    try:
        # 从请求头中获取 Token
        authorization = request.headers.get("Authorization")
        # print("authorization??????", authorization)
        if not authorization or not authorization.startswith("Bearer "):
            raise HTTPException(status_code=401, detail="缺少有效的 Token")
        token = authorization.split(" ")[1]
        print("token!!!!!!!", token)
        # 验证 Token 
        payload = await verify_token(token, return_payload=True)
        print("palyload>>>>>>>>>>>>>>>>>>", payload)
        username = payload.get("sub")
        exp = payload.get("exp")
        # 将用户名附加到请求上下文中
        request.state.username = username
        request.state.exp = exp
    except HTTPException as e:
        logger.error(f"Token 验证失败: {e.detail}")
        return JSONResponse(status_code=e.status_code, content={"detail": e.detail})
    except Exception as e:
        logger.error(f"Token 验证发生未知错误: {str(e)}")
        return JSONResponse(status_code=500, content={"detail": "Token 验证发生未知错误"})
    # Token 验证通过，继续处理请求
    logger.info(f"Token 验证通过: 用户名: {username}, 过期时间: {exp}")
    response = await call_next(request)
    return response
